home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / amiutils / i_l / irit5 / irit / objects1.c < prev    next >
C/C++ Source or Header  |  1995-12-30  |  34KB  |  855 lines

  1. /*****************************************************************************
  2. *   "Irit" - the 3d (not only polygonal) solid modeller.             *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.2, Mar. 1990   *
  5. ******************************************************************************
  6. *   Module to handle the objects list - fetch, insert, delete etc...         *
  7. *****************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <ctype.h>
  12. #include <math.h>
  13. #include "program.h"
  14. #include "allocate.h"
  15. #include "attribut.h"
  16. #include "primitiv.h"
  17. #include "geomat3d.h"
  18. #include "objects.h"
  19. #include "freeform.h"
  20. #include "windows.h"
  21.  
  22. #define IS_FLOAT_PRINTF_CMD(c)    ((c) == 'e' || (c) == 'f' || (c) == 'g' || \
  23.                  (c) == 'E' || (c) == 'F')
  24. #define IS_PRINTF_CMD(c)  (IS_FLOAT_PRINTF_CMD(c) || \
  25.                (c) == 'd' || (c) == 'i' || (c) == 'u' || \
  26.                (c) == 'o' || (c) == 'x' || (c) == 'X' || \
  27.                (c) == 's' || (c) == 'p' || (c) == 'v' || \
  28.                (c) == 'P' || (c) == 'D')
  29.  
  30. static IPPolygonStruct *GenAxesObjectPolylines(void);
  31.  
  32. /*****************************************************************************
  33. * DESCRIPTION:                                                               M
  34. * Routine to set up all the predefined objects - objects that the system     M
  35. *   must have all the time, like global transformation matrices.         M
  36. *                                                                            *
  37. * PARAMETERS:                                                                M
  38. *   None                                                                     *
  39. *                                                                            *
  40. * RETURN VALUE:                                                              M
  41. *   void                                                                     M
  42. *                                                                            M
  43. * KEYWORDS:                                                                  M
  44. *   SetUpPredefObjects                                                       M
  45. *****************************************************************************/
  46. void SetUpPredefObjects(void)
  47. {
  48.     RealType R;
  49.     MatrixType Mat1, Mat2;
  50.     IPObjectStruct *PObj;
  51.  
  52.     /* 90 - 35.2644 = 54.7356 */
  53.     MatGenMatRotX1(DEG2RAD(-54.7356), Mat1); /* Generate default view trans. */
  54.     MatGenMatRotZ1(M_PI+M_PI/4, Mat2);         /* which is isometric view. */
  55.     MatMultTwo4by4(Mat2, Mat2, Mat1);
  56.     PObj = GenMatObject("VIEW_MAT", Mat2, NULL);
  57.     InsertObject(PObj);
  58.  
  59.     MatGenUnitMat(Mat1);          /* Generate default perspective trans. */
  60.     Mat1[2][2] = 0.1;
  61.     Mat1[2][3] = -0.35;
  62.     Mat1[3][2] = 0.35;
  63.     PObj = GenMatObject("PRSP_MAT", Mat1, NULL);
  64.     InsertObject(PObj);
  65.  
  66.     R = DEFAULT_RESOLUTION;
  67.     PObj = GenNumObject("RESOLUTION", &R, NULL);
  68.     InsertObject(PObj);
  69.  
  70.     R = DEFAULT_DRAW_CTLPT;
  71.     PObj = GenNumObject("DRAWCTLPT", &R, NULL);
  72.     InsertObject(PObj);
  73.  
  74.     R = 0;
  75.     PObj = GenNumObject("FLAT4PLY", &R, NULL);
  76.     InsertObject(PObj);
  77.  
  78.     R = 0;
  79.     PObj = GenNumObject("POLY_APPROX_OPT", &R, NULL);
  80.     InsertObject(PObj);
  81.  
  82.     R = 0;
  83.     PObj = GenNumObject("POLY_APPROX_UV", &R, NULL);
  84.     InsertObject(PObj);
  85.  
  86.     R = 0.3;
  87.     PObj = GenNumObject("POLY_APPROX_TOL", &R, NULL);
  88.     InsertObject(PObj);
  89.  
  90.     R = MACHINE_UNIX;
  91. #if defined(__MSDOS__) || defined(DJGCC)
  92.     R = MACHINE_MSDOS;
  93. #endif
  94. #if defined(sgi)
  95.     R = MACHINE_SGI;
  96. #endif
  97. #if defined(hpbsd) || defined(hpux) || defined(__hpux)
  98.     R = MACHINE_HP;
  99. #endif
  100. #if defined(sun)
  101.     R = MACHINE_SUN;
  102. #endif
  103. #if defined(apollo)
  104.     R = MACHINE_APOLLO;
  105. #endif
  106. #if defined(OS2GCC)
  107.     R = MACHINE_IBMOS2;
  108. #endif
  109. #if defined(WIN32NT)
  110.     R = MACHINE_IBMNT;
  111. #endif
  112. #if defined(AMIGA)
  113.     R = MACHINE_AMIGA;
  114. #endif
  115.  
  116.     PObj = GenNumObject("MACHINE", &R, NULL);
  117.     InsertObject(PObj);
  118.  
  119.     PObj = GenPolyObject("AXES", GenAxesObjectPolylines(), NULL);
  120.     IP_SET_POLYLINE_OBJ(PObj);              /* Mark it as polyline object. */
  121.     InsertObject(PObj);
  122. }
  123.  
  124. /*****************************************************************************
  125. * DESCRIPTION:                                                               M
  126. * Routine to set an attribute of an object.                     M
  127. *                                                                            *
  128. * PARAMETERS:                                                                M
  129. *   PObj:     To set an attribute for.                                       M
  130. *   Name:     Name of attribute.                                             M
  131. *   Data:     new value of attribute                                         M
  132. *                                                                            *
  133. * RETURN VALUE:                                                              M
  134. *   void                                                                     M
  135. *                                                                            *
  136. * KEYWORDS:                                                                  M
  137. *   SetObjectAttrib                                                          M
  138. *****************************************************************************/
  139. void SetObjectAttrib(IPObjectStruct *PObj, char *Name, IPObjectStruct *Data)
  140. {
  141.     if (IP_IS_STR_OBJ(Data))
  142.     AttrSetObjectStrAttrib(PObj, Name, Data -> U.Str);
  143.     else if (IP_IS_NUM_OBJ(Data)) {
  144.     RealType
  145.         r = Data -> U.R;
  146.  
  147.     if (r == (int) r)
  148.         AttrSetObjectIntAttrib(PObj, Name, (int) r);
  149.     else
  150.         AttrSetObjectRealAttrib(PObj, Name, r);
  151.     }
  152.     else
  153.         AttrSetObjectObjAttrib(PObj, Name, Data, TRUE);
  154. }
  155.  
  156. /*****************************************************************************
  157. * DESCRIPTION:                                                               M
  158. * Routine to remove an attribute from an object.                 M
  159. *                                                                            *
  160. * PARAMETERS:                                                                M
  161. *   PObj:     To remover an attribute from.                                  M
  162. *   Name:     Name of attribute.                                             M
  163. *                                                                            *
  164. * RETURN VALUE:                                                              M
  165. *   void                                                                     M
  166. *                                                                            *
  167. * KEYWORDS:                                                                  M
  168. *   RemoveObjectAttrib                                                       M
  169. *****************************************************************************/
  170. void RemoveObjectAttrib(IPObjectStruct *PObj, char *Name)
  171. {
  172.     AttrFreeOneAttribute(&PObj -> Attrs, Name);
  173. }
  174.  
  175. /*****************************************************************************
  176. * DESCRIPTION:                                                               *
  177. * Generate an axis coordinate system with length of 1 on each axis.         *
  178. *                                                                            *
  179. * PARAMETERS:                                                                *
  180. *   None                                                                     *
  181. *                                                                            *
  182. * RETURN VALUE:                                                              *
  183. *   IPPolygonStruct *:   A polyline representing the XYZ coordinate system.  *
  184. *****************************************************************************/
  185. static IPPolygonStruct *GenAxesObjectPolylines(void)
  186. {
  187.     IPPolygonStruct *Pl, *PlHead;
  188.     IPVertexStruct *V;
  189.  
  190.     /* X axis. */
  191.     Pl = PlHead = IPAllocPolygon(0, 0, NULL, NULL);
  192.     Pl -> PVertex = V = IPAllocVertex(0, 0, NULL, NULL);
  193.     V -> Coord[0] = 0.0;    V -> Coord[1] = 0.0;   V -> Coord[2] = 0.0;
  194.     V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  195.     V -> Coord[0] = 1.0;    V -> Coord[1] = 0.0;   V -> Coord[2] = 0.0;
  196.     V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  197.     V -> Coord[0] = 1.0;    V -> Coord[1] = 0.1;   V -> Coord[2] = 0.1;
  198.  
  199.     Pl -> Pnext = IPAllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;
  200.     Pl -> PVertex = V = IPAllocVertex(0, 0, NULL, NULL);
  201.     V -> Coord[0] = 1.0;    V -> Coord[1] = 0.1;   V -> Coord[2] = 0.0;
  202.     V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  203.     V -> Coord[0] = 1.0;    V -> Coord[1] = 0.0;   V -> Coord[2] = 0.1;
  204.  
  205.     /* Y axis.*/
  206.     Pl -> Pnext = IPAllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;
  207.     Pl -> PVertex = V = IPAllocVertex(0, 0, NULL, NULL);
  208.     V -> Coord[0] = 0.0;    V -> Coord[1] = 0.0;   V -> Coord[2] = 0.0;
  209.     V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  210.     V -> Coord[0] = 0.0;    V -> Coord[1] = 1.0;   V -> Coord[2] = 0.0;
  211.     V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  212.     V -> Coord[0] = 0.0;    V -> Coord[1] = 1.0;   V -> Coord[2] = 0.06;
  213.     V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  214.     V -> Coord[0] = 0.04;   V -> Coord[1] = 1.0;   V -> Coord[2] = 0.1;
  215.     V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  216.     V -> Coord[0] = 0.0;    V -> Coord[1] = 1.0;   V -> Coord[2] = 0.06;
  217.     V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  218.     V -> Coord[0] =(-0.04); V -> Coord[1] = 1.0;   V -> Coord[2] = 0.1;
  219.  
  220.     /* Z axis.*/
  221.     Pl -> Pnext = IPAllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;
  222.     Pl -> PVertex = V = IPAllocVertex(0, 0, NULL, NULL);
  223.     V -> Coord[0] = 0.0;    V -> Coord[1] = 0.0;   V -> Coord[2] = 0.0;
  224.     V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  225.     V -> Coord[0] = 0.0;    V -> Coord[1] = 0.0;   V -> Coord[2] = 1.0;
  226.     V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  227.     V -> Coord[0] = 0.1;    V -> Coord[1] = 0.0;   V -> Coord[2] = 1.0;
  228.     V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  229.     V -> Coord[0] = 0.0;    V -> Coord[1] = 0.1;   V -> Coord[2] = 1.0;
  230.     V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  231.     V -> Coord[0] = 0.1;    V -> Coord[1] = 0.1;   V -> Coord[2] = 1.0;
  232.  
  233.     return PlHead;
  234. }
  235.  
  236. /*****************************************************************************
  237. * DESCRIPTION:                                                               M
  238. * Returns the type of an object.                         M
  239. *   If object is not found, an undefined type is returned.                   M
  240. *                                                                            *
  241. * PARAMETERS:                                                                M
  242. *   Name:       Of object to query type.                                     M
  243. *                                                                            *
  244. * RETURN VALUE:                                                              M
  245. *   double:     Type of object, coerced to double                            M
  246. *                                                                            *
  247. * KEYWORDS:                                                                  M
  248. *   ThisObjectIs                                                             M
  249. *****************************************************************************/
  250. double ThisObjectIs(char *Name)
  251. {
  252.     int i;
  253.     IPObjectStruct *PObj;
  254.  
  255.     for (i = 0; i < strlen(Name); i++)
  256.     if (islower(Name[i]))
  257.         Name[i] = toupper(Name[i]);
  258.  
  259.     PObj = GetObject(Name);
  260.  
  261.     return (double) (PObj == NULL ? IP_OBJ_UNDEF : (PObj -> ObjType));
  262. }
  263.  
  264. /*****************************************************************************
  265. * DESCRIPTION:                                                               M
  266. * General printf routine, IRIT's style, to stdout.                 M
  267. *                                                                            *
  268. * PARAMETERS:                                                                M
  269. *   CtlStr:     Control string of this printf.                               M
  270. *   PObjLst:    List of object to print.                                     M
  271. *                                                                            *
  272. * RETURN VALUE:                                                              M
  273. *   void                                                                     M
  274. *                                                                            *
  275. * KEYWORDS:                                                                  M
  276. *   IritObjectPrintfStdout                                                   M
  277. *****************************************************************************/
  278. void IritObjectPrintfStdout(char *CtlStr, IPObjectStruct *PObjLst)
  279. {
  280.     IritObjectPrintf(stdout, CtlStr, PObjLst);
  281. }
  282.  
  283. /*****************************************************************************
  284. * DESCRIPTION:                                                               M
  285. * General printf routine, IRIT's style.                              M
  286. *                                                                            *
  287. * PARAMETERS:                                                                M
  288. *   File:       File descriptor of where this all goes.                      M
  289. *   CtlStr:     Control string of this printf.                               M
  290. *   PObjLst:    List of object to print.                                     M
  291. *                                                                            *
  292. * RETURN VALUE:                                                              M
  293. *   void                                                                     M
  294. *                                                                            *
  295. * KEYWORDS:                                                                  M
  296. *   IritObjectPrintf                                                         M
  297. *****************************************************************************/
  298. void IritObjectPrintf(FILE *File, char *CtlStr, IPObjectStruct *PObjLst)
  299. {
  300.     char Buffer[LINE_LEN], Line[LINE_LEN_LONG];
  301.     int i, j, k,
  302.     CrntItem = 0,
  303.     NumOfItems = ListObjectLength(PObjLst);
  304.     IPObjectStruct *CrntObj;
  305.  
  306.     Line[0] = 0;
  307.  
  308.     for (i = 0; i < strlen(CtlStr); i++) {
  309.     if (CtlStr[i] == '%') {
  310.         for (j = 0; j < 10 && !IS_PRINTF_CMD(CtlStr[i]); j++, i++)
  311.         Buffer[j] = CtlStr[i];
  312.         Buffer[j++] = CtlStr[i];
  313.         Buffer[j--] = 0;
  314.  
  315.         if (CrntItem >= NumOfItems) {
  316.         WndwInputWindowPutStr("PRINTF: Not enough objects for printf.");
  317.         return;
  318.         }
  319.         CrntObj = ListObjectGet(PObjLst, CrntItem++);
  320.  
  321.         switch (Buffer[j]) {
  322.         case 'c':
  323.             if (IP_IS_NUM_OBJ(CrntObj)) {
  324.             sprintf(&Line[strlen(Line)], Buffer,
  325.                 (int) CrntObj -> U.R);
  326.             }
  327.             else {
  328.             WndwInputWindowPutStr("PRINTF: Number expected.");
  329.             return;
  330.             }
  331.             break;
  332.         case 'd':
  333.         case 'i':
  334.         case 'u':
  335.         case 'o':
  336.         case 'x':
  337.         case 'X':
  338.             if (IP_IS_NUM_OBJ(CrntObj)) {
  339.             sprintf(&Line[strlen(Line)], Buffer,
  340.                 (int) CrntObj -> U.R);
  341.             }
  342.             else {
  343.             WndwInputWindowPutStr("PRINTF: Number expected.");
  344.             return;
  345.             }
  346.             break;
  347.         case 'e':
  348.         case 'f':
  349.         case 'g':
  350.         case 'E':
  351.         case 'G':
  352.             if (IP_IS_NUM_OBJ(CrntObj)) {
  353.             sprintf(&Line[strlen(Line)], Buffer,
  354.                 CrntObj -> U.R);
  355.             }
  356.             else {
  357.             WndwInputWindowPutStr("PRINTF: Number expected.");
  358.             return;
  359.             }
  360.             break;
  361.         case 's':
  362.             if (IP_IS_STR_OBJ(CrntObj)) {
  363.             sprintf(&Line[strlen(Line)], Buffer,
  364.                 CrntObj -> U.Str);
  365.             }
  366.             else {
  367.             WndwInputWindowPutStr("PRINTF: String expected.");
  368.             return;
  369.             }
  370.             break;
  371.         case 'p':
  372.         case 'v':
  373.             if (!IP_IS_VEC_OBJ(CrntObj) &&
  374.             !IP_IS_POINT_OBJ(CrntObj)) {
  375.             WndwInputWindowPutStr(
  376.                 "PRINTF: Vector or Point expected.");
  377.             return;
  378.             }
  379.             Buffer[j] = CtlStr[++i];
  380.             if (!IS_FLOAT_PRINTF_CMD(Buffer[j])) {
  381.             WndwInputWindowPutStr(
  382.                 "PRINTF: Floaing point number command expected.");
  383.             return;
  384.             }
  385.             for (k = 0; k < 3; k++) {
  386.             sprintf(&Line[strlen(Line)],
  387.                 Buffer, CrntObj -> U.Vec[k]);
  388.             if (k < 2)
  389.                 strcat(Line, ", ");
  390.             }
  391.             break;
  392.         case 'P':
  393.             if (!IP_IS_PLANE_OBJ(CrntObj)) {
  394.             WndwInputWindowPutStr("PRINTF: Plane expected.");
  395.             return;
  396.             }
  397.             Buffer[j] = CtlStr[++i];
  398.             if (!IS_FLOAT_PRINTF_CMD(Buffer[j])) {
  399.             WndwInputWindowPutStr(
  400.                 "PRINTF: Floaing point number command expected.");
  401.             return;
  402.             }
  403.             for (k = 0; k < 4; k++) {
  404.             sprintf(&Line[strlen(Line)],
  405.                 Buffer, CrntObj -> U.Plane[k]);
  406.             if (k < 3)
  407.                 strcat(Line, ", ");
  408.             }
  409.             break;
  410.         case 'D':
  411.             Buffer[j] = CtlStr[++i];
  412.             IritPrsrSetFloatFormat(Buffer);
  413.  
  414.             if (strlen(Line) > 0) {
  415.             WndwInputWindowPutStr(Line);
  416.             Line[0] = 0;
  417.             }
  418.             PrintObject(CrntObj);
  419.             IritPrsrSetFloatFormat(GlblFloatFormat);
  420.             break;
  421.         default:
  422.             WndwInputWindowPutStr(
  423.             "PRINTF: Unknown % control to print command.");
  424.             return;
  425.         }
  426.     }
  427.     else if (CtlStr[i] == '\\') {
  428.         k = strlen(Line);
  429.  
  430.         switch (CtlStr[++i]) {
  431.         case 't':
  432.             Line[k] = '\t';
  433.             break;
  434.         case 'n':
  435.             Line[k] = '\n';
  436.             break;
  437.         case '%':
  438.             Line[k] = '%';
  439.             break;
  440.         }
  441.         Line[++k] = 0;
  442.  
  443.     }
  444.     else {
  445.         k = strlen(Line);
  446.         Line[k++] = CtlStr[i];
  447.         Line[k] = 0;
  448.     }
  449.     }
  450.     if (strlen(Line) > 0)
  451.     WndwInputWindowPutStr(Line);
  452. }
  453.  
  454. /*****************************************************************************
  455. * DESCRIPTION:                                                               M
  456. * Gets the size of an object.                             M
  457. *                                                                            *
  458. * PARAMETERS:                                                                M
  459. *   Obj:      Object to query size of.                                       M
  460. *                                                                            *
  461. * RETURN VALUE:                                                              M
  462. *   double:   Size of object Obj, coerced to double.                         M
  463. *                                                                            *
  464. * KEYWORDS:                                                                  M
  465. *   GetObjectSize                                                            M
  466. *****************************************************************************/
  467. double GetObjectSize(IPObjectStruct *Obj)
  468. {
  469.     if (IP_IS_POLY_OBJ(Obj)) {
  470.     if (Obj -> U.Pl -> Pnext == NULL)
  471.         return (double) IritPrsrVrtxListLen(Obj -> U.Pl -> PVertex);
  472.     else
  473.         return (double) IritPrsrPolyListLen(Obj -> U.Pl);
  474.     }
  475.     else if (IP_IS_CRV_OBJ(Obj)) {
  476.     return (double) Obj -> U.Crvs -> Length;
  477.     }
  478.     else if (IP_IS_OLST_OBJ(Obj)) {
  479.     return (double) ListObjectLength(Obj);
  480.     }
  481.     else {
  482.     WndwInputWindowPutStr("Sizeof: cannot compute object size.");
  483.         return 0.0;
  484.     }
  485. }
  486.  
  487. /*****************************************************************************
  488. * DESCRIPTION:                                                               M
  489. * Gets the size of a surface mesh.                         M
  490. *                                                                            *
  491. * PARAMETERS:                                                                M
  492. *   SrfObj:    Surface toquery its mesh size.                                M
  493. *   RDir:      Direction to query size.                                      M
  494. *                                                                            *
  495. * RETURN VALUE:                                                              M
  496. *   double:    Size of mesh of SrfObj in direction RDir.                     M
  497. *                                                                            *
  498. * KEYWORDS:                                                                  M
  499. *   GetMeshSize                                                              M
  500. *****************************************************************************/
  501. double GetMeshSize(IPObjectStruct *SrfObj, RealType *RDir)
  502. {
  503.     int Dir = REAL_PTR_TO_INT(RDir);
  504.  
  505.     if (IP_IS_SRF_OBJ(SrfObj)) {
  506.     return (double) (Dir ? SrfObj -> U.Srfs -> ULength
  507.                  : SrfObj -> U.Srfs -> VLength);
  508.     }
  509.     else {
  510.     WndwInputWindowPutStr("MeshSize: cannot compute non surface object size.");
  511.         return 0.0;
  512.     }
  513. }
  514.  
  515. /*****************************************************************************
  516. * DESCRIPTION:                                                               M
  517. * Creates an empty list.                                  M
  518. *                                                                            *
  519. * PARAMETERS:                                                                M
  520. *   None                                                                     *
  521. *                                                                            *
  522. * RETURN VALUE:                                                              M
  523. *   IPObjectStruct *:   A  list object with emtpy list.                      M
  524. *                                                                            *
  525. * KEYWORDS:                                                                  M
  526. *   GetNilList                                                               M
  527. *****************************************************************************/
  528. IPObjectStruct *GetNilList(void)
  529. {
  530.     IPObjectStruct
  531.     *PObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  532.  
  533.     ListObjectInsert(PObj, 0, NULL);
  534.  
  535.     return PObj;
  536. }
  537.  
  538. /*****************************************************************************
  539. * DESCRIPTION:                                                               M
  540. * Gets the nth object in a list.                         M
  541. *                                                                            *
  542. * PARAMETERS:                                                                M
  543. *   ListObj:   List object to query its n'th element.                        M
  544. *   Rn:        The n'th element of ListObj is needed.                        M
  545. *                                                                            *
  546. * RETURN VALUE:                                                              M
  547. *   IPObjectStruct *:  The n'th element of ListObj                           M
  548. *                                                                            *
  549. * KEYWORDS:                                                                  M
  550. *   GetNthList                                                               M
  551. *****************************************************************************/
  552. IPObjectStruct *GetNthList(IPObjectStruct *ListObj, RealType *Rn)
  553. {
  554.     int n = REAL_PTR_TO_INT(Rn);
  555.  
  556.     IPObjectStruct *PObj;
  557.  
  558.     if (!IP_IS_OLST_OBJ(ListObj)) {
  559.     WndwInputWindowPutStr("None list object ignored.");
  560.         return NULL;
  561.     }
  562.  
  563.     if (n < 1 || n > ListObjectLength(ListObj)) {
  564.     WndwInputWindowPutStr("Out of range of list.");
  565.         return NULL;
  566.     }
  567.  
  568.     PObj = CopyObject(NULL, ListObjectGet(ListObj, n - 1), FALSE);
  569.     return PObj;
  570. }
  571.  
  572. /*****************************************************************************
  573. * DESCRIPTION:                                                               M
  574. * Appends two lists.                                                         M
  575. *                                                                            *
  576. * PARAMETERS:                                                                M
  577. *   ListObj1, ListObj2:  The two list objects to append.                     M
  578. *                                                                            *
  579. * RETURN VALUE:                                                              M
  580. *   IPObjectStruct *:    A combined list.                                    M
  581. *                                                                            *
  582. * KEYWORDS:                                                                  M
  583. *   AppendLists                                                              M
  584. *****************************************************************************/
  585. IPObjectStruct *AppendLists(IPObjectStruct *ListObj1, IPObjectStruct *ListObj2)
  586. {
  587.     int i, j;
  588.     IPObjectStruct *PObj, *PObjTmp;
  589.  
  590.     if (!IP_IS_OLST_OBJ(ListObj1) && !IP_IS_OLST_OBJ(ListObj2)) {
  591.     WndwInputWindowPutStr("None list object ignored.");
  592.     return NULL;
  593.     }
  594.  
  595.     PObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  596.  
  597.     for (i = 0; (PObjTmp = ListObjectGet(ListObj1, i)) != NULL; i++) {
  598.     ListObjectInsert(PObj, i, PObjTmp);
  599.     PObjTmp -> Count++;
  600.     }
  601.  
  602.     for (j = 0; (PObjTmp = ListObjectGet(ListObj2, j)) != NULL; i++, j++) {
  603.     ListObjectInsert(PObj, i, PObjTmp);
  604.     PObjTmp -> Count++;
  605.     }
  606.  
  607.     ListObjectInsert(PObj, i, NULL);
  608.  
  609.     return PObj;
  610. }
  611.  
  612. /*****************************************************************************
  613. * DESCRIPTION:                                                               M
  614. * Reverses a list.                                                           M
  615. *                                                                            *
  616. * PARAMETERS:                                                                M
  617. *   ListObj:    List object to reverses its entries.                         M
  618. *                                                                            *
  619. * RETURN VALUE:                                                              M
  620. *   IPObjectStruct *:   Reversed list object.                                M
  621. *                                                                            *
  622. * KEYWORDS:                                                                  M
  623. *   ReverseListObj                                                           M
  624. *****************************************************************************/
  625. IPObjectStruct *ReverseListObj(IPObjectStruct *ListObj)
  626. {
  627.     int i, j;
  628.     IPObjectStruct *PObj, *PObjTmp;
  629.  
  630.     if (!IP_IS_OLST_OBJ(ListObj)) {
  631.     WndwInputWindowPutStr("None list object ignored.");
  632.     return NULL;
  633.     }
  634.  
  635.     PObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  636.  
  637.     for (i = ListObjectLength(ListObj) - 1, j = 0; i >= 0; i--) {
  638.     PObjTmp = ListObjectGet(ListObj, i);
  639.     ListObjectInsert(PObj, j++, PObjTmp);
  640.     PObjTmp -> Count++;
  641.     }
  642.  
  643.     ListObjectInsert(PObj, j, NULL);
  644.  
  645.     return PObj;
  646. }
  647.  
  648. /*****************************************************************************
  649. * DESCRIPTION:                                                               M
  650. * Snoc (Cons to the end of the list, in place) the object to the list in     M
  651. * the second argument.                                 M
  652. *                                                                            *
  653. * PARAMETERS:                                                                M
  654. *   PObj:      To snoc to ListObj.                                           M
  655. *   ListObj:   Where PObj is going to be added to, in place.                 M
  656. *                                                                            *
  657. * RETURN VALUE:                                                              M
  658. *   void                                                                     M
  659. *                                                                            *
  660. * KEYWORDS:                                                                  M
  661. *   SnocList                                                                 M
  662. *****************************************************************************/
  663. void SnocList(IPObjectStruct *PObj, IPObjectStruct *ListObj)
  664. {
  665.     int i;
  666.     IPObjectStruct *PObjTmp;
  667.  
  668.     if (!IP_IS_OLST_OBJ(ListObj)) {
  669.     WndwInputWindowPutStr("None list object ignored.");
  670.     return;
  671.     }
  672.  
  673.     i = ListObjectLength(ListObj);
  674.     ListObjectInsert(ListObj, i, PObjTmp = CopyObject(NULL, PObj, FALSE));
  675.     PObjTmp -> Count = 1;
  676.     ListObjectInsert(ListObj, i + 1, NULL);
  677. }
  678.  
  679. /*****************************************************************************
  680. * DESCRIPTION:                                                               M
  681. * Gets an object by its name - scans the object linear list.             M
  682. *  The termination is also on 1000 objects (simple debugging aid in case     M
  683. * the Object list became circular), and a fatal error is produced.         M
  684. *                                                                            *
  685. * PARAMETERS:                                                                M
  686. *   ObjName:      Name of object to search for.                              M
  687. *                                                                            *
  688. * RETURN VALUE:                                                              M
  689. *   IPObjectStruct *:   Object if found, NULL otherwise.                     M
  690. *                                                                            *
  691. * KEYWORDS:                                                                  M
  692. *   GetObject                                                                M
  693. *****************************************************************************/
  694. IPObjectStruct *GetObject(char *ObjName)
  695. {
  696.     int i = 0;
  697.     IPObjectStruct
  698.     *PObj = GlblObjList;
  699.  
  700.     while (PObj) {
  701.     if (strcmp(PObj -> Name, ObjName) == 0) {
  702.         return PObj;
  703.     }
  704.     PObj = PObj -> Pnext;
  705.     if (i++ >= 1000)
  706.         IritFatalError("GetObject: Global Object list too big (>1000)");
  707.     }
  708.     return NULL;
  709. }
  710.  
  711. /*****************************************************************************
  712. * DESCRIPTION:                                                               M
  713. * Extract a single entity out af an obj holding a set of entities at Index.  M
  714. *   For VECTOR, POINT, CTLPT, PLANE, MAT a single numeric data is returned.  M
  715. *   For a POLYGON a single vertex is returned (as VECTOR).             M
  716. *   For CURVE, and SURFACE a single control point is returned.             M
  717. *                                                                            *
  718. * PARAMETERS:                                                                M
  719. *   PObj:      To query for one of its coordinates.                          M
  720. *   RIndex:    Index of coordinate.                                          M
  721. *                                                                            *
  722. * RETURN VALUE:                                                              M
  723. *   IPObjectStruct *:  An object holding the Index coordinate of PObj.       M
  724. *                                                                            *
  725. * KEYWORDS:                                                                  M
  726. *   GetObjectCoord                                                           M
  727. *****************************************************************************/
  728. IPObjectStruct *GetObjectCoord(IPObjectStruct *PObj, RealType *RIndex)
  729. {
  730.     int Index = REAL_PTR_TO_INT(RIndex);
  731.     IPObjectStruct
  732.     *CoordPObj = NULL;
  733.     CagdCtlPtStruct CtlPt;
  734.  
  735.     switch (PObj -> ObjType) {
  736.     case IP_OBJ_POLY:
  737.         if (PObj -> U.Pl == NULL)
  738.         break;
  739.         if (PObj -> U.Pl -> Pnext) {
  740.         IPPolygonStruct *P;
  741.  
  742.         /* Extract a single poly from the poly list. */
  743.         for (P = PObj -> U.Pl;
  744.              P != NULL && Index > 0;
  745.              P = P -> Pnext, Index--);
  746.         if (P != NULL) {
  747.             IPPolygonStruct
  748.                 *PTmp = IPAllocPolygon(1, P -> Tags,
  749.                     CopyVertexList(P -> PVertex), NULL);
  750.  
  751.             CoordPObj = GenPolyObject("", PTmp, NULL);
  752.             PLANE_COPY(PTmp -> Plane, P -> Plane);
  753.             IP_RST_BBOX_POLY(PTmp);
  754.             CoordPObj -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  755.  
  756.             if (IP_IS_POLYGON_OBJ(PObj))
  757.                 IP_SET_POLYGON_OBJ(CoordPObj);
  758.             else if (IP_IS_POLYLINE_OBJ(PObj))
  759.                 IP_SET_POLYLINE_OBJ(CoordPObj);
  760.             else if (IP_IS_POINTLIST_OBJ(PObj))
  761.                 IP_SET_POINTLIST_OBJ(CoordPObj);
  762.         }
  763.         }
  764.         else {
  765.         IPVertexStruct *V;
  766.  
  767.         /* Extract a vertex from the poly. */
  768.         for (V = PObj -> U.Pl -> PVertex;
  769.              V != NULL && Index > 0;
  770.              V = V -> Pnext, Index--);
  771.         if (V != NULL)
  772.           CoordPObj = GenVECObject(&V -> Coord[0], &V -> Coord[1],
  773.                        &V -> Coord[2]);
  774.         }
  775.         break;
  776.     case IP_OBJ_POINT:
  777.         if (Index >= 0 && Index < 3)
  778.         CoordPObj = GenNUMValObject(PObj -> U.Pt[Index]);
  779.         break;
  780.     case IP_OBJ_VECTOR:
  781.         if (Index >= 0 && Index < 3)
  782.         CoordPObj = GenNUMValObject(PObj -> U.Pt[Index]);
  783.         break;
  784.     case IP_OBJ_PLANE:
  785.         if (Index >= 0 && Index < 4)
  786.         CoordPObj = GenNUMValObject(PObj -> U.Pt[Index]);
  787.         break;
  788.     case IP_OBJ_CTLPT:
  789.         if (!CAGD_IS_RATIONAL_PT(PObj -> U.CtlPt.PtType) && Index == 0)
  790.         break;
  791.         if (Index >= 0 &&
  792.         Index <= CAGD_NUM_OF_PT_COORD(PObj -> U.CtlPt.PtType))
  793.         CoordPObj = GenNUMValObject(PObj -> U.CtlPt.Coords[Index]);
  794.         break;
  795.     case IP_OBJ_MATRIX:
  796.         if (Index >= 0 && Index < 16)
  797.         CoordPObj =
  798.             GenNUMValObject((*PObj -> U.Mat)[Index / 4][Index % 4]);
  799.         break;
  800.     case IP_OBJ_LIST_OBJ:
  801.         CoordPObj = GetNthList(PObj, RIndex);
  802.         break;
  803.     case IP_OBJ_CURVE:
  804.         if (PObj -> U.Crvs == NULL)
  805.             break;
  806.         if (PObj -> U.Crvs -> Pnext != NULL) {
  807.         CagdCrvStruct *Crv;
  808.  
  809.         /* Extract a single curve from the curve list. */
  810.         for (Crv = PObj -> U.Crvs;
  811.              Crv != NULL && Index > 0;
  812.              Crv = Crv -> Pnext, Index--);
  813.         if (Crv != NULL)
  814.             CoordPObj = GenCRVObject(CagdCrvCopy(Crv));
  815.         }
  816.         else {
  817.         /* Extract a ctlpt from the curve. */
  818.         CagdEditSingleCrvPt(PObj -> U.Crvs, &CtlPt, Index, FALSE);
  819.         CoordPObj = GenCTLPTObject(PObj -> U.Crvs -> PType,
  820.                        CtlPt.Coords, NULL);
  821.         }
  822.         break;
  823.     case IP_OBJ_SURFACE:
  824.         if (PObj -> U.Srfs == NULL)
  825.             break;
  826.         if (PObj -> U.Srfs -> Pnext != NULL) {
  827.         CagdSrfStruct *Srf;
  828.  
  829.         /* Extract a single surface from the surface list. */
  830.         for (Srf = PObj -> U.Srfs;
  831.              Srf != NULL && Index > 0;
  832.              Srf = Srf -> Pnext, Index--);
  833.         if (Srf != NULL)
  834.             CoordPObj = GenSRFObject(CagdSrfCopy(Srf));
  835.         }
  836.         else {
  837.         /* Extract a ctlpt from the surface. */
  838.         CagdEditSingleSrfPt(PObj -> U.Srfs, &CtlPt,
  839.                     Index / PObj -> U.Srfs -> ULength,
  840.                     Index % PObj -> U.Srfs -> ULength,
  841.                     FALSE);
  842.         CoordPObj = GenCTLPTObject(PObj -> U.Srfs -> PType,
  843.                        CtlPt.Coords, NULL);
  844.         }
  845.         break;
  846.     default:
  847.         break;
  848.     }
  849.  
  850.    if (CoordPObj == NULL)
  851.        WndwInputWindowPutStr("Coord: Out of range or wrong object type.");
  852.  
  853.     return CoordPObj;
  854. }
  855.